package com.platform.modules.sys.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.platform.common.annotation.SysLog;
import com.platform.common.page.PageUtil;
import com.platform.common.utils.RestResponse;
import com.platform.common.validator.ValidatorUtils;
import com.platform.common.validator.group.AddGroup;
import com.platform.common.validator.group.UpdateGroup;
import com.platform.modules.sys.entity.SysDictEntity;
import com.platform.modules.sys.entity.SysDictGroupEntity;
import com.platform.modules.sys.service.SysDictGroupService;
import com.platform.modules.sys.service.SysDictService;

import javax.servlet.http.HttpServletResponse;

/**
 * 数据字典Controller
 *
 * @author 肖亮
 */
@Api(tags = "SysDictController|数据字典管理")
@RestController
@RequestMapping("sys/dict")
public class SysDictController {
    private Map<String, Object> parms;

    @Autowired
    private SysDictService sysDictService;
    @Autowired
    private SysDictGroupService sysDictGroupService;

    /**
     * 查看所有列表
     *
     * @param status 查询参数
     * @return RestResponse
     */

    @ApiOperation(value = "查询数据字典列表", notes = "根据条件获取数据字典")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "name", value = "数据字典名称", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "code", value = "数据字典码", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "status", value = "数据字典状态", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "groupId", value = "所属分组ID", dataType = "String")
    })
    @PostMapping("/queryAll")
    public RestResponse queryAll(String name, String code, String status,String groupId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("name", name);
        params.put("code", code);
        params.put("status", status);
        params.put("groupId", groupId);
        List<SysDictEntity> list = sysDictService.queryList(params);
        return RestResponse.success().put("list", list);
    }


    /**
     * 分页查询
     *
     * @param name 查询参数
     * @return RestResponse
     */
    @ApiOperation(value = "查询数据字典列表", notes = "根据条件获取数据字典")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "currPage", value = "当前页数", dataType = "Integer"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "分页步数", dataType = "Integer"),
            @ApiImplicitParam(paramType = "query", name = "name", value = "数据字典名称", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "code", value = "数据字典码", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "value", value = "数据字典值", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "groupId", value = "所属分组ID", dataType = "String")
    })
    @PostMapping("/list")
    public RestResponse list(Integer currPage, Integer limit, String name, String code, String value, String groupId) {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("name", name);
        params.put("code", code);
        params.put("value", value);
        params.put("groupId", groupId);
        params.put("page", PageUtil.getCurrPage(currPage));
        params.put("limit", PageUtil.getLimit(limit));
        IPage page = sysDictService.queryPage(params);

        return RestResponse.success().put("page", page);
    }

    /**
     * 根据主键查询详情
     *
     * @param id 主键
     * @return RestResponse
     */
    @ApiOperation(value = "查询数据字典详情", notes = "根据主键查询数据字典详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "数据字典主键", dataType = "String")
    })
    @PostMapping("/info")
    public RestResponse info(String id) {

        SysDictEntity sysDict = sysDictService.getById(id);

        return RestResponse.success().put("dict", sysDict);
    }

    /**
     * 保存
     *
     * @return RestResponse
     */
    @ApiOperation(value = "保存数据字典", notes = "保存数据字典")
    @ApiImplicitParams({

    })
    @SysLog("保存数据字典")
    @PostMapping("/save")
    @RequiresPermissions("sys:dict:save")
    public RestResponse save(SysDictEntity sysDict) {
        ValidatorUtils.validateEntity(sysDict, AddGroup.class);
        sysDictService.add(sysDict);

        return RestResponse.success();
    }

    /**
     * 修改
     *
     * @return RestResponse
     */
    @ApiOperation(value = "修改数据字典", notes = "修改数据字典")
    @SysLog("修改数据字典")
    @PostMapping("/update")
    @RequiresPermissions("sys:dict:update")
    public RestResponse update(SysDictEntity sysDict) {
        ValidatorUtils.validateEntity(sysDict, UpdateGroup.class);
        sysDictService.update(sysDict);

        return RestResponse.success();
    }

    /**
     * 删除
     *
     * @param ids ids
     * @return RestResponse
     */
    @ApiOperation(value = "删除数据字典", notes = "根据id删除模型（支持多id删除）")
    @SysLog("删除数据字典")
    @PostMapping("/delete")
    @RequiresPermissions("sys:dict:delete")
    public RestResponse delete(String[] ids) {
        sysDictService.deleteBatch(ids);

        return RestResponse.success();
    }

    /**
     * 根据code查询数据字典
     *
     * @param code 查询参数
     * @return RestResponse
     */
    @ApiOperation(value = "查询数据字典", notes = "根据code查询数据字典")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "code", value = "数据字典字段code", dataType = "String")
    })
    @PostMapping("/queryByCode")
    public RestResponse queryByCode(String code) {
        if (code == null || "".equals(code)) {
            return RestResponse.error("请输入正确字典code值！");
        }
        Map<String, Object> params = new HashMap<String, Object>();
        SysDictGroupEntity sysDictGroupEntity = sysDictGroupService
                .getOne(new QueryWrapper<SysDictGroupEntity>().eq(StringUtils.isNotBlank(code), "code", code));
        String type = "";
        if (null != sysDictGroupEntity) {
            type = sysDictGroupEntity.getName();
        }
        params.put("code", code);
        List<SysDictEntity> list = sysDictService.queryByCode(params);
        return RestResponse.success().put("list", list).put("type", type);
    }

    @ApiOperation("获取据系统字典项的js文件@auther(lipf)")
    @PostMapping("/value/jsDictFile.js")
    public void jsDictFile(HttpServletResponse response) {
        try {
            response.setContentType("application/javascript; charset=GB2312");
            PrintWriter out = response.getWriter();
            BufferedWriter bw = new BufferedWriter(out);

            bw.write("/*");
            bw.newLine();
            bw.write("* @Author: lipengfei");
            bw.newLine();
            bw.write("* @Date:   2018-08-28");
            bw.newLine();
            bw.write("* +----------------------------------------------------------------------");
            bw.newLine();
            bw.write("* | admin [ 后台管理系统公共配置信息  ]");
            bw.newLine();
            bw.write("* | 配置信息，包含接口");
            bw.newLine();
            bw.write("* +----------------------------------------------------------------------");
            bw.newLine();
            bw.write("*/");
            bw.newLine();
            bw.write("layui.define(function (exports) {");
            bw.newLine();
            bw.write("var jsDictFile = {");
            bw.newLine();

            List<SysDictGroupEntity> sysDictGroupList = sysDictGroupService.queryAll(new HashMap<>());
            if (null != sysDictGroupList) {
                for (SysDictGroupEntity sysDictGroup : sysDictGroupList) {
                    JSONArray jsonArray = new JSONArray();
                    JSONObject groupObject = new JSONObject();
                    groupObject.put("groupId", sysDictGroup.getId());
                    groupObject.put("name", sysDictGroup.getName());
                    groupObject.put("code", sysDictGroup.getCode());
                    parms = new HashMap<>();
                    parms.put("groupId", sysDictGroup.getCode());
                    parms.put("parentId", null);
                    parms.put("status", "1");
                    List<SysDictEntity> sysDictList = sysDictService.queryByCodeAndParentId(parms);
                    if (sysDictList != null && sysDictList.size() != 0) {
                        //递归
                        JSONArray dictArray = recurse(sysDictList);
                        groupObject.put("childrens", dictArray);
                    }
                    jsonArray.add(groupObject);
                    bw.write(" //" + sysDictGroup.getName() + " ");
                    bw.newLine();
                    bw.write(sysDictGroup.getCode() + " : " + jsonArray.toString() + ",");
                    bw.newLine();
                    bw.newLine();
                }
            }


            //获取枚举信息
		/*StringBuffer enumInfoBuff = new StringBuffer();
		for(Class<?> clazz:dictFileEnumList){

			Object[] objects= clazz.getEnumConstants();
			Method getKey = clazz.getMethod("getKey");
			Method getName = clazz.getMethod("getName");
			String jsName= clazz.getAnnotation(DictFile.class).jsName();
			String jsText= clazz.getAnnotation(DictFile.class).jsText();
			JSONArray  jsonArrayDict = new JSONArray();
			for (Object object : objects) {
				JSONObject  dictValueJSON=new JSONObject();
				dictValueJSON.put("value", getKey.invoke(object));
				dictValueJSON.put("name", getName.invoke(object));
				jsonArrayDict.add(dictValueJSON);
			}
			enumInfoBuff.append("\r\n");
			enumInfoBuff.append(" //"+jsText );
			enumInfoBuff.append("\r\n");
			enumInfoBuff.append(" "+jsName+" : "+jsonArrayDict.toString()+",");
		}
		String enumInfo= enumInfoBuff.substring(0,enumInfoBuff.length()-1);
		bw.write(enumInfo);*/
            bw.newLine();
            bw.newLine();
            bw.write("};");
            bw.newLine();
            bw.write("exports('jsDictFile', jsDictFile);");
            bw.newLine();
            bw.write("});");
            bw.newLine();
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * @Auther: Zhouxw
     * @Date: 2019-6-26 16:48
     * @Description: 递归操作
     */
    public JSONArray recurse(List<SysDictEntity> sysDictList) {
        JSONArray array = new JSONArray();
        for (SysDictEntity dict : sysDictList) {
            JSONObject obj = new JSONObject();
            obj.put("value", dict.getValue());
            obj.put("name", dict.getName());
            obj.put("dictId", dict.getId());
            parms.put("parentId", dict.getId());
            List<SysDictEntity> childList = sysDictService.queryByCodeAndParentId(parms);
            if (null != childList && childList.size() > 0) {
                JSONArray arrayEnd = recurse(childList);
                obj.put("childrens", arrayEnd);
            }
            array.add(obj);
        }
        return array;
    }
}
